<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>多功能文本编辑器 - 任务7完成版</title>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
    <style>
        :root {
            /* 高亮主题变量 */
            --highlight-background: #1e1e1e;
            --highlight-foreground: #d4d4d4;
            --highlight-keyword: #569cd6;
            --highlight-string: #ce9178;
            --highlight-comment: #6a9955;
            --highlight-number: #b5cea8;
            --highlight-operator: #d4d4d4;
            --highlight-type: #4ec9b0;
            --highlight-builtin: #dcdcaa;
            --highlight-bracket: #ffd700;
            --border-color: #e0e0e0;
        }
        
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            height: 100vh;
            overflow: hidden;
        }
        
        .editor-container {
            display: flex;
            flex-direction: column;
            height: 100vh;
            background: white;
            box-shadow: 0 0 20px rgba(0,0,0,0.1);
        }
        
        .editor-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 15px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        
        .editor-title {
            font-size: 1.5em;
            font-weight: 600;
        }
        
        .editor-status {
            display: flex;
            gap: 20px;
            font-size: 0.9em;
            opacity: 0.9;
        }
        
        .status-item {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .status-indicator {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #4CAF50;
        }
        
        .status-indicator.saving {
            background: #FF9800;
            animation: pulse 1s infinite;
        }
        
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        
        .toolbar {
            background: #fafafa;
            border-bottom: 1px solid #e0e0e0;
            padding: 10px 20px;
            display: flex;
            gap: 15px;
            align-items: center;
            flex-wrap: wrap;
        }
        
        .toolbar-group {
            display: flex;
            gap: 5px;
            align-items: center;
            padding-right: 15px;
            border-right: 1px solid #e0e0e0;
        }
        
        .toolbar-group:last-child {
            border-right: none;
        }
        
        .toolbar-btn {
            padding: 8px 12px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .toolbar-btn:hover {
            background: #f0f0f0;
            border-color: #ccc;
        }
        
        .toolbar-btn.active {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .toolbar-btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            background: #f9f9f9;
        }
        
        .toolbar-btn:disabled:hover {
            background: #f9f9f9;
            border-color: #ddd;
        }
        
        .toolbar-select {
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            background: white;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.2s ease;
        }
        
        .toolbar-select:hover {
            border-color: #ccc;
        }
        
        .toolbar-select:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .editor-main {
            display: flex;
            flex: 1;
            overflow: hidden;
        }
        
        .editor-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            position: relative;
        }
        
        .editor-workspace {
            flex: 1;
            position: relative;
            overflow: hidden;
            display: flex;
        }
        
        /* 行号显示 */
        .line-numbers {
            background: var(--highlight-background);
            color: #858585;
            padding: 20px 10px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.6;
            text-align: right;
            user-select: none;
            border-right: 1px solid var(--border-color);
            min-width: 60px;
            overflow: hidden;
        }
        
        .line-number {
            height: 22.4px;
            display: flex;
            align-items: center;
            justify-content: flex-end;
        }
        
        /* 编辑器主体 */
        .editor-body {
            flex: 1;
            position: relative;
            overflow: hidden;
        }
        
        /* 高亮层 */
        .highlight-layer {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            padding: 20px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.6;
            white-space: pre;
            overflow: auto;
            pointer-events: none;
            z-index: 1;
            background: var(--highlight-background);
            color: var(--highlight-foreground);
        }
        
        /* 语法高亮样式 */
        .highlight-layer .keyword {
            color: var(--highlight-keyword);
            font-weight: bold;
        }
        
        .highlight-layer .string {
            color: var(--highlight-string);
        }
        
        .highlight-layer .comment {
            color: var(--highlight-comment);
            font-style: italic;
        }
        
        .highlight-layer .number {
            color: var(--highlight-number);
        }
        
        .highlight-layer .operator {
            color: var(--highlight-operator);
        }
        
        .highlight-layer .type {
            color: var(--highlight-type);
        }
        
        .highlight-layer .builtin {
            color: var(--highlight-builtin);
        }
        
        .highlight-layer .bracket {
            color: var(--highlight-bracket);
            font-weight: bold;
        }
        
        .editor-textarea {
            width: 100%;
            height: 100%;
            border: none;
            outline: none;
            padding: 20px;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
            font-size: 14px;
            line-height: 1.6;
            resize: none;
            white-space: pre;
            overflow: auto;
            transition: all 0.2s ease;
            z-index: 2;
            position: relative;
        }
        
        .editor-textarea.transparent {
            background: transparent;
            color: transparent;
            caret-color: var(--highlight-foreground);
        }
        
        .editor-footer {
            background: #f5f5f5;
            border-top: 1px solid #e0e0e0;
            padding: 8px 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 12px;
            color: #666;
        }
        
        .footer-left {
            display: flex;
            gap: 20px;
        }
        
        .footer-right {
            display: flex;
            gap: 20px;
        }
        
        .context-menu {
            position: fixed;
            background: white;
            border: 1px solid #ddd;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 1000;
            min-width: 150px;
            padding: 5px 0;
        }
        
        .context-menu-item {
            padding: 8px 15px;
            cursor: pointer;
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 14px;
            transition: background 0.2s ease;
        }
        
        .context-menu-item:hover {
            background: #f0f0f0;
        }
        
        .context-menu-item.disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        
        .context-menu-divider {
            height: 1px;
            background: #e0e0e0;
            margin: 5px 0;
        }
        
        .shortcut {
            margin-left: auto;
            font-size: 12px;
            color: #999;
        }
        
        /* 查找替换面板样式 */
        .search-replace {
            position: absolute;
            top: 10px;
            right: 10px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 8px 24px rgba(0,0,0,0.15);
            z-index: 500;
            min-width: 350px;
            max-width: 400px;
        }
        
        .search-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .search-header h4 {
            margin: 0;
            color: #333;
            font-size: 16px;
        }
        
        .close-btn {
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            color: #999;
            padding: 0;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 4px;
        }
        
        .close-btn:hover {
            background: #f0f0f0;
            color: #666;
        }
        
        .search-inputs {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        .search-input-group {
            display: flex;
            gap: 8px;
            align-items: center;
        }
        
        .search-input {
            flex: 1;
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
        }
        
        .search-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .search-btn {
            padding: 8px 12px;
            border: 1px solid #ddd;
            background: white;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            transition: all 0.2s ease;
        }
        
        .search-btn:hover {
            background: #f0f0f0;
        }
        
        .search-btn.primary {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .search-btn.primary:hover {
            background: #5a6fd8;
        }
        
        .search-options {
            display: flex;
            gap: 15px;
            margin-bottom: 15px;
            font-size: 13px;
        }
        
        .search-option {
            display: flex;
            align-items: center;
            gap: 5px;
        }
        
        .search-option input[type="checkbox"] {
            margin: 0;
        }
        
        .search-actions {
            display: flex;
            gap: 8px;
            justify-content: flex-end;
        }
        
        .search-status {
            background: #e3f2fd;
            border: 1px solid #bbdefb;
            border-radius: 4px;
            padding: 8px;
            margin-bottom: 10px;
            font-size: 12px;
            color: #0d47a1;
            text-align: center;
        }
        
        /* 字数统计面板样式 */
        .stats-panel {
            position: absolute;
            top: 10px;
            left: 10px;
            background: white;
            border: 1px solid #ddd;
            border-radius: 8px;
            padding: 20px;
            box-shadow: 0 8px 24px rgba(0,0,0,0.15);
            z-index: 500;
            min-width: 300px;
            max-width: 400px;
        }
        
        .stats-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .stats-section {
            margin-bottom: 15px;
        }
        
        .stats-section h5 {
            margin: 0 0 10px 0;
            color: #333;
            font-size: 14px;
            font-weight: 600;
        }
        
        .stats-item {
            display: flex;
            justify-content: space-between;
            padding: 5px 0;
            font-size: 13px;
            border-bottom: 1px solid #f5f5f5;
        }
        
        .stats-item:last-child {
            border-bottom: none;
        }
        
        .stats-item span:first-child {
            color: #666;
        }
        
        .stats-item span:last-child {
            font-weight: 600;
            color: #333;
        }
        
        /* 模态框样式 */
        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 2000;
        }
        
        .modal {
            background: white;
            border-radius: 8px;
            padding: 20px;
            min-width: 300px;
            max-width: 500px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
        }
        
        .modal-header {
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        
        .modal-header h3 {
            margin: 0;
            color: #333;
        }
        
        .modal-content {
            margin-bottom: 20px;
        }
        
        .modal-input {
            width: 100%;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
            margin-top: 10px;
        }
        
        .modal-input:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.2);
        }
        
        .modal-actions {
            display: flex;
            gap: 10px;
            justify-content: flex-end;
        }
        
        .modal-btn {
            padding: 10px 20px;
            border: 1px solid #ddd;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
            transition: all 0.2s ease;
        }
        
        .modal-btn.primary {
            background: #667eea;
            color: white;
            border-color: #667eea;
        }
        
        .modal-btn.primary:hover {
            background: #5a6fd8;
        }
        
        .modal-btn:hover {
            background: #f0f0f0;
        }
        
        .drag-overlay {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(102, 126, 234, 0.1);
            border: 3px dashed #667eea;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2em;
            color: #667eea;
            font-weight: 600;
            z-index: 1000;
        }
        
        .toast {
            position: fixed;
            top: 20px;
            right: 20px;
            background: #4CAF50;
            color: white;
            padding: 12px 20px;
            border-radius: 6px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            z-index: 3000;
            animation: slideInRight 0.3s ease;
        }
        
        .toast.error {
            background: #f44336;
        }
        
        .toast.warning {
            background: #ff9800;
        }
        
        @keyframes slideInRight {
            from {
                opacity: 0;
                transform: translateX(100%);
            }
            to {
                opacity: 1;
                transform: translateX(0);
            }
        }
        
        /* 任务完成提示样式 */
        .task-completed {
            background: #d4edda;
            border: 1px solid #c3e6cb;
            border-radius: 4px;
            padding: 10px;
            margin: 10px;
            font-size: 12px;
            color: #155724;
        }
        
        .task-completed strong {
            color: #0f5132;
        }
        
        /* 全屏模式样式 */
        .fullscreen-mode {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            z-index: 9999;
            background: white;
        }
        
        .fullscreen-mode .editor-container {
            height: 100vh;
        }
        
        /* VS Code Light 主题 */
        .vs-light {
            --highlight-background: #ffffff;
            --highlight-foreground: #000000;
            --highlight-keyword: #0000ff;
            --highlight-string: #a31515;
            --highlight-comment: #008000;
            --highlight-number: #098658;
            --highlight-operator: #000000;
            --highlight-type: #267f99;
            --highlight-builtin: #795e26;
            --highlight-bracket: #0431fa;
        }
        
        /* Monokai 主题 */
        .monokai {
            --highlight-background: #272822;
            --highlight-foreground: #f8f8f2;
            --highlight-keyword: #f92672;
            --highlight-string: #e6db74;
            --highlight-comment: #75715e;
            --highlight-number: #ae81ff;
            --highlight-operator: #f8f8f2;
            --highlight-type: #66d9ef;
            --highlight-builtin: #a6e22e;
            --highlight-bracket: #f8f8f2;
        }
    </style>
</head>
<body>
    <div id="app">
        <div class="editor-container" :class="{ 'fullscreen-mode': isFullscreen, [currentTheme]: true }">
            <!-- 编辑器头部 -->
            <div class="editor-header">
                <div class="editor-title">多功能文本编辑器 - 任务7完成版</div>
                <div class="editor-status">
                    <div class="status-item">
                        <div class="status-indicator" :class="{ saving: isSaving }"></div>
                        <span>{{ saveStatus }}</span>
                    </div>
                    <div class="status-item">
                        <span>{{ fontSize }}px {{ fontFamily }}</span>
                    </div>
                    <div class="status-item" v-if="wordWrap">
                        <span>自动换行</span>
                    </div>
                    <div class="status-item" v-if="isFullscreen">
                        <span>全屏模式</span>
                    </div>
                    <div class="status-item" v-if="highlightEnabled">
                        <span>{{ currentLanguage }} 高亮</span>
                    </div>
                    <div class="status-item" v-if="totalMatches > 0">
                        <span>{{ currentMatchIndex + 1 }}/{{ totalMatches }}</span>
                    </div>
                    <div class="status-item">
                        <span>{{ currentTime }}</span>
                    </div>
                </div>
            </div>
            
            <!-- 工具栏 -->
            <div class="toolbar">
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务1已完成:</strong> 文件操作功能
                    </div>
                    <button class="toolbar-btn" @click="newFile" title="新建文件 (Ctrl+N)">
                        📄 新建
                    </button>
                    <button class="toolbar-btn" @click="openFile" title="打开文件 (Ctrl+O)">
                        📁 打开
                    </button>
                    <button class="toolbar-btn" @click="saveFile" title="保存文件 (Ctrl+S)">
                        💾 保存
                    </button>
                    <button class="toolbar-btn" @click="saveAsFile" title="另存为 (Ctrl+Shift+S)">
                        📋 另存为
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务2已完成:</strong> 撤销/重做功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        @click="undo" 
                        :disabled="!canUndo"
                        title="撤销 (Ctrl+Z)"
                    >
                        ↶ 撤销
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="redo" 
                        :disabled="!canRedo"
                        title="重做 (Ctrl+Y)"
                    >
                        ↷ 重做
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务3已完成:</strong> 编辑操作功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        @click="cut" 
                        :disabled="!selectedText"
                        title="剪切 (Ctrl+X)"
                    >
                        ✂️ 剪切
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="copy" 
                        :disabled="!selectedText"
                        title="复制 (Ctrl+C)"
                    >
                        📋 复制
                    </button>
                    <button 
                        class="toolbar-btn" 
                        @click="paste" 
                        title="粘贴 (Ctrl+V)"
                    >
                        📌 粘贴
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务4已完成:</strong> 格式设置功能
                    </div>
                    <select 
                        class="toolbar-select" 
                        v-model="fontSize" 
                        @change="updateFontSize"
                        title="字体大小"
                    >
                        <option value="12">12px</option>
                        <option value="14">14px</option>
                        <option value="16">16px</option>
                        <option value="18">18px</option>
                        <option value="20">20px</option>
                        <option value="24">24px</option>
                    </select>
                    
                    <select 
                        class="toolbar-select" 
                        v-model="fontFamily" 
                        @change="updateFontFamily"
                        title="字体类型"
                    >
                        <option value="Consolas">Consolas</option>
                        <option value="Monaco">Monaco</option>
                        <option value="Courier New">Courier New</option>
                        <option value="monospace">Monospace</option>
                    </select>
                    
                    <button 
                        class="toolbar-btn" 
                        @click="toggleWordWrap" 
                        :class="{ active: wordWrap }"
                        title="自动换行 (Alt+Z)"
                    >
                        🔄 换行
                    </button>
                    
                    <button 
                        class="toolbar-btn" 
                        @click="toggleFullscreen" 
                        :class="{ active: isFullscreen }"
                        title="全屏模式 (F11)"
                    >
                        {{ isFullscreen ? '🗗' : '🗖' }} 全屏
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务5已完成:</strong> 查找替换功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        @click="toggleSearchPanel" 
                        :class="{ active: showSearchPanel }"
                        title="查找替换 (Ctrl+F)"
                    >
                        🔍 查找
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务6已完成:</strong> 字数统计功能
                    </div>
                    <button 
                        class="toolbar-btn" 
                        @click="toggleStatsPanel" 
                        :class="{ active: showStatsPanel }"
                        title="字数统计 (Ctrl+Shift+W)"
                    >
                        📊 统计
                    </button>
                </div>
                
                <div class="toolbar-group">
                    <div class="task-completed">
                        <strong>任务7新增:</strong> 关键字高亮功能
                    </div>
                    <select 
                        class="toolbar-select" 
                        v-model="currentLanguage" 
                        @change="updateLanguage"
                        title="编程语言"
                    >
                        <option value="javascript">JavaScript</option>
                        <option value="html">HTML</option>
                        <option value="css">CSS</option>
                        <option value="python">Python</option>
                        <option value="json">JSON</option>
                        <option value="markdown">Markdown</option>
                        <option value="text">纯文本</option>
                    </select>
                    
                    <select 
                        class="toolbar-select" 
                        v-model="currentTheme" 
                        @change="updateTheme"
                        title="高亮主题"
                    >
                        <option value="vs-dark">VS Code Dark</option>
                        <option value="vs-light">VS Code Light</option>
                        <option value="monokai">Monokai</option>
                    </select>
                    
                    <button 
                        class="toolbar-btn" 
                        @click="toggleHighlight" 
                        :class="{ active: highlightEnabled }"
                        title="语法高亮 (Alt+H)"
                    >
                        🎨 高亮
                    </button>
                    
                    <button 
                        class="toolbar-btn" 
                        @click="toggleLineNumbers" 
                        :class="{ active: showLineNumbers }"
                        title="行号显示 (Alt+L)"
                    >
                        🔢 行号
                    </button>
                </div>
            </div>
            
            <!-- 编辑器主体 -->
            <div class="editor-main">
                <div class="editor-content">
                    <!-- 字数统计面板 -->
                    <div v-if="showStatsPanel" class="stats-panel">
                        <div class="stats-header">
                            <h4>📊 字数统计</h4>
                            <button class="close-btn" @click="toggleStatsPanel">×</button>
                        </div>
                        
                        <div class="stats-section">
                            <h5>📄 文档统计</h5>
                            <div class="stats-item">
                                <span>字符数:</span>
                                <span>{{ formatNumber(documentStats.characters) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>单词数:</span>
                                <span>{{ formatNumber(documentStats.words) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>行数:</span>
                                <span>{{ formatNumber(documentStats.lines) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>非空行数:</span>
                                <span>{{ formatNumber(documentStats.nonEmptyLines) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>段落数:</span>
                                <span>{{ formatNumber(documentStats.paragraphs) }}</span>
                            </div>
                        </div>
                        
                        <div class="stats-section" v-if="selectedTextLength > 0">
                            <h5>✂️ 选中文本统计</h5>
                            <div class="stats-item">
                                <span>字符数:</span>
                                <span>{{ formatNumber(selectionStats.characters) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>单词数:</span>
                                <span>{{ formatNumber(selectionStats.words) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>行数:</span>
                                <span>{{ formatNumber(selectionStats.lines) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>非空行数:</span>
                                <span>{{ formatNumber(selectionStats.nonEmptyLines) }}</span>
                            </div>
                            <div class="stats-item">
                                <span>段落数:</span>
                                <span>{{ formatNumber(selectionStats.paragraphs) }}</span>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 查找替换面板 -->
                    <div v-if="showSearchPanel" class="search-replace">
                        <div class="search-header">
                            <h4>🔍 查找和替换</h4>
                            <button class="close-btn" @click="toggleSearchPanel">×</button>
                        </div>
                        
                        <div v-if="totalMatches > 0" class="search-status">
                            找到 {{ totalMatches }} 个匹配项
                        </div>
                        
                        <div class="search-inputs">
                            <div class="search-input-group">
                                <input 
                                    ref="searchInput"
                                    v-model="searchText" 
                                    class="search-input" 
                                    placeholder="查找内容..."
                                    @input="performSearch"
                                    @keydown="handleSearchKeydown"
                                >
                                <button class="search-btn" @click="findNext" :disabled="totalMatches === 0">
                                    ↓
                                </button>
                                <button class="search-btn" @click="findPrevious" :disabled="totalMatches === 0">
                                    ↑
                                </button>
                            </div>
                            
                            <div class="search-input-group">
                                <input 
                                    v-model="replaceText" 
                                    class="search-input" 
                                    placeholder="替换为..."
                                    @keydown="handleSearchKeydown"
                                >
                                <button class="search-btn primary" @click="replaceOne" :disabled="totalMatches === 0">
                                    替换
                                </button>
                                <button class="search-btn primary" @click="replaceAll" :disabled="totalMatches === 0">
                                    全部
                                </button>
                            </div>
                        </div>
                        
                        <div class="search-options">
                            <div class="search-option">
                                <input type="checkbox" id="caseSensitive" v-model="caseSensitive" @change="performSearch">
                                <label for="caseSensitive">区分大小写</label>
                            </div>
                            <div class="search-option">
                                <input type="checkbox" id="wholeWord" v-model="wholeWord" @change="performSearch">
                                <label for="wholeWord">全字匹配</label>
                            </div>
                        </div>
                    </div>
                    
                    <!-- 编辑器工作区 -->
                    <div class="editor-workspace">
                        <!-- 行号 -->
                        <div v-if="showLineNumbers" class="line-numbers" ref="lineNumbers">
                            <div v-for="(line, index) in contentLines" :key="index" class="line-number">
                                {{ index + 1 }}
                            </div>
                        </div>
                        
                        <!-- 编辑器主体 -->
                        <div class="editor-body">
                            <!-- 高亮层 -->
                            <div 
                                v-if="highlightEnabled" 
                                class="highlight-layer" 
                                ref="highlightLayer"
                                v-html="highlightedContent"
                            ></div>
                            
                            <!-- 文本编辑区 -->
                            <textarea 
                                ref="textarea"
                                v-model="content"
                                class="editor-textarea"
                                :class="{ transparent: highlightEnabled }"
                                @input="handleInput"
                                @scroll="handleScroll"
                                @select="handleSelectionChange"
                                @keydown="handleKeydown"
                                @contextmenu="showContextMenu"
                                :style="{
                                    fontSize: fontSize + 'px',
                                    fontFamily: fontFamily,
                                    whiteSpace: wordWrap ? 'pre-wrap' : 'pre'
                                }"
                                spellcheck="false"
                                placeholder="开始输入您的代码或文本..."
                            ></textarea>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- 编辑器页脚 -->
            <div class="editor-footer">
                <div class="footer-left">
                    <span>行 {{ cursorPosition.line }}, 列 {{ cursorPosition.column }}</span>
                    <span v-if="selectedTextLength > 0">(已选择 {{ selectedTextLength }} 个字符)</span>
                    <span>{{ contentLines.length }} 行</span>
                    <span v-if="currentFileName">{{ currentFileName }}</span>
                </div>
                <div class="footer-right">
                    <span v-if="highlightEnabled">{{ currentLanguage.toUpperCase() }}</span>
                    <span>{{ currentTheme }}</span>
                    <span>UTF-8</span>
                    <span>{{ saveStatus }}</span>
                </div>
            </div>
            
            <!-- 右键菜单 -->
            <div v-if="contextMenuVisible" class="context-menu" :style="{ left: contextMenuPosition.x + 'px', top: contextMenuPosition.y + 'px' }">
                <div class="context-menu-item" @click="cut" :class="{ disabled: !selectedText }">
                    ✂️ 剪切
                    <span class="shortcut">Ctrl+X</span>
                </div>
                <div class="context-menu-item" @click="copy" :class="{ disabled: !selectedText }">
                    📋 复制
                    <span class="shortcut">Ctrl+C</span>
                </div>
                <div class="context-menu-item" @click="paste">
                    📌 粘贴
                    <span class="shortcut">Ctrl+V</span>
                </div>
                <div class="context-menu-divider"></div>
                <div class="context-menu-item" @click="selectAll">
                    🔘 全选
                    <span class="shortcut">Ctrl+A</span>
                </div>
                <div class="context-menu-divider"></div>
                <div class="context-menu-item" @click="toggleSearchPanel">
                    🔍 查找替换
                    <span class="shortcut">Ctrl+F</span>
                </div>
                <div class="context-menu-item" @click="toggleStatsPanel">
                    📊 字数统计
                    <span class="shortcut">Ctrl+Shift+W</span>
                </div>
                <div class="context-menu-item" @click="toggleHighlight">
                    🎨 语法高亮
                    <span class="shortcut">Alt+H</span>
                </div>
            </div>
            
            <!-- 拖拽覆盖层 -->
            <div v-if="isDragging" class="drag-overlay">
                📁 拖拽文件到此处打开
            </div>
        </div>
        
        <!-- Toast 通知 -->
        <div v-if="toast.show" class="toast" :class="toast.type">
            {{ toast.message }}
        </div>
        
        <!-- 模态框 -->
        <div v-if="modal.show" class="modal-overlay" @click="modal.show = false">
            <div class="modal" @click.stop>
                <div class="modal-header">
                    <h3>{{ modal.title }}</h3>
                </div>
                <div class="modal-content">
                    <p>{{ modal.message }}</p>
                    <input 
                        v-if="modal.type === 'prompt'" 
                        ref="modalInput"
                        v-model="modal.inputValue" 
                        class="modal-input" 
                        :placeholder="modal.placeholder"
                        @keydown.enter="confirmModal"
                        @keydown.escape="cancelModal"
                    >
                </div>
                <div class="modal-actions">
                    <button v-if="modal.type !== 'alert'" class="modal-btn" @click="cancelModal">
                        取消
                    </button>
                    <button class="modal-btn primary" @click="confirmModal">
                        {{ modal.type === 'alert' ? '确定' : '确认' }}
                    </button>
                </div>
            </div>
        </div>
    </div>

    <script>
        const { createApp, ref, computed, watch, onMounted, onUnmounted, nextTick } = Vue;
        
        createApp({
            setup() {
                // 基础数据
                const content = ref('');
                const currentFileName = ref('');
                const saveStatus = ref('已保存');
                const isSaving = ref(false);
                const currentTime = ref('');
                const isDragging = ref(false);
                
                // 历史记录
                const history = ref([]);
                const historyIndex = ref(-1);
                const maxHistorySize = 100;
                
                // 选择和光标
                const selectedText = ref('');
                const selectionStart = ref(0);
                const selectionEnd = ref(0);
                const cursorLine = ref(1);
                const cursorColumn = ref(1);
                const cursorPosition = ref({ line: 1, column: 1 });
                
                // 格式设置
                const fontSize = ref(14);
                const fontFamily = ref('Consolas');
                const wordWrap = ref(false);
                const isFullscreen = ref(false);
                
                // 查找替换
                const showSearchPanel = ref(false);
                const showFindPanel = ref(false);
                const searchText = ref('');
                const replaceText = ref('');
                const caseSensitive = ref(false);
                const wholeWord = ref(false);
                const currentMatchIndex = ref(-1);
                const searchMatches = ref([]);
                
                // 字数统计
                const showStatsPanel = ref(false);
                
                // 关键字高亮 - 任务7新增
                const highlightEnabled = ref(true);
                const currentLanguage = ref('javascript');
                const currentTheme = ref('vs-dark');
                const showLineNumbers = ref(true);
                const highlightedContent = ref('');
                const isHighlighting = ref(false);
                
                // 右键菜单
                const contextMenuVisible = ref(false);
                const contextMenuPosition = ref({ x: 0, y: 0 });
                
                // Toast 通知
                const toast = ref({
                    show: false,
                    message: '',
                    type: 'success'
                });
                
                // Toast 通知 - 单独变量
                const toastVisible = ref(false);
                const toastMessage = ref('');
                const toastType = ref('success');
                
                // 模态框
                const modal = ref({
                    show: false,
                    type: 'alert',
                    title: '',
                    message: '',
                    placeholder: '',
                    inputValue: '',
                    resolve: null,
                    reject: null
                });
                
                // 模态框 - 单独变量
                const modalVisible = ref(false);
                const modalType = ref('alert');
                const modalTitle = ref('');
                const modalMessage = ref('');
                const modalInputValue = ref('');
                const modalResolve = ref(null);
                const modalReject = ref(null);
                
                // 右键菜单坐标
                const contextMenuX = ref(0);
                const contextMenuY = ref(0);
                
                // 计算属性
                const canUndo = computed(() => historyIndex.value > 0);
                const canRedo = computed(() => historyIndex.value < history.value.length - 1);
                const selectedTextLength = computed(() => selectedText.value.length);
                const contentLines = computed(() => content.value.split('\n'));
                const totalMatches = computed(() => searchMatches.value.length);
                
                // 文档统计
                const documentStats = computed(() => calculateStats(content.value));
                
                // 选择文本统计
                const selectionStats = computed(() => calculateStats(selectedText.value));
                
                // 语言定义 - 任务7新增
                const languages = {
                    javascript: {
                        keywords: ['function', 'var', 'let', 'const', 'if', 'else', 'for', 'while', 'do', 'switch', 'case', 'default', 'break', 'continue', 'return', 'try', 'catch', 'finally', 'throw', 'class', 'extends', 'constructor', 'super', 'this', 'new', 'typeof', 'instanceof', 'in', 'of', 'import', 'export', 'from', 'as', 'default', 'async', 'await', 'yield', 'static', 'get', 'set', 'delete', 'void', 'with', 'debugger'],
                        types: ['String', 'Number', 'Boolean', 'Array', 'Object', 'Date', 'RegExp', 'Function', 'Promise', 'Symbol', 'Map', 'Set', 'WeakMap', 'WeakSet'],
                        builtins: ['console', 'window', 'document', 'localStorage', 'sessionStorage', 'JSON', 'Math', 'parseInt', 'parseFloat', 'isNaN', 'isFinite', 'encodeURIComponent', 'decodeURIComponent', 'setTimeout', 'setInterval', 'clearTimeout', 'clearInterval'],
                        operators: ['+', '-', '*', '/', '%', '=', '==', '===', '!=', '!==', '<', '>', '<=', '>=', '&&', '||', '!', '&', '|', '^', '~', '<<', '>>', '>>>', '++', '--', '+=', '-=', '*=', '/=', '%=', '&=', '|=', '^=', '<<=', '>>=', '>>>='],
                        brackets: ['(', ')', '[', ']', '{', '}'],
                        strings: ['\'', '"', '`'],
                        comments: ['//', '/*', '*/'],
                        numbers: /\b\d+(\.\d+)?([eE][+-]?\d+)?\b/g
                    },
                    html: {
                        keywords: ['html', 'head', 'body', 'title', 'meta', 'link', 'script', 'style', 'div', 'span', 'p', 'a', 'img', 'ul', 'ol', 'li', 'table', 'tr', 'td', 'th', 'form', 'input', 'button', 'textarea', 'select', 'option', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'br', 'hr', 'strong', 'em', 'b', 'i', 'u', 'small', 'sub', 'sup'],
                        types: ['DOCTYPE', 'html', 'xmlns'],
                        builtins: ['class', 'id', 'src', 'href', 'alt', 'title', 'style', 'onclick', 'onload', 'type', 'name', 'value', 'placeholder', 'required', 'disabled', 'readonly'],
                        operators: ['='],
                        brackets: ['<', '>', '/', '"', '\''],
                        strings: ['"', '\''],
                        comments: ['<!--', '-->'],
                        numbers: /\b\d+(\.\d+)?\b/g
                    },
                    css: {
                        keywords: ['color', 'background', 'font', 'margin', 'padding', 'border', 'width', 'height', 'display', 'position', 'top', 'left', 'right', 'bottom', 'float', 'clear', 'overflow', 'z-index', 'opacity', 'visibility', 'cursor', 'text-align', 'text-decoration', 'line-height', 'letter-spacing', 'word-spacing', 'white-space', 'vertical-align', 'list-style', 'table-layout', 'border-collapse', 'border-spacing', 'caption-side', 'empty-cells', 'quotes', 'content', 'counter-reset', 'counter-increment'],
                        types: ['px', 'em', 'rem', '%', 'vh', 'vw', 'pt', 'pc', 'in', 'cm', 'mm', 'ex', 'ch', 'vmin', 'vmax'],
                        builtins: ['important', 'inherit', 'initial', 'unset', 'auto', 'none', 'normal', 'bold', 'italic', 'underline', 'overline', 'line-through', 'uppercase', 'lowercase', 'capitalize'],
                        operators: [':', ';', '{', '}', '(', ')', ',', '>', '+', '~', '*'],
                        brackets: ['{', '}', '(', ')', '[', ']'],
                        strings: ['"', '\''],
                        comments: ['/*', '*/'],
                        numbers: /\b\d+(\.\d+)?(px|em|rem|%|vh|vw|pt|pc|in|cm|mm|ex|ch|vmin|vmax)?\b/g
                    },
                    python: {
                        keywords: ['and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', 'pass', 'print', 'raise', 'return', 'try', 'while', 'with', 'yield', 'True', 'False', 'None'],
                        types: ['int', 'float', 'str', 'list', 'dict', 'tuple', 'set', 'bool', 'bytes', 'bytearray', 'complex', 'frozenset', 'range', 'slice', 'type', 'object'],
                        builtins: ['abs', 'all', 'any', 'bin', 'bool', 'chr', 'dir', 'divmod', 'enumerate', 'eval', 'filter', 'format', 'getattr', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'isinstance', 'issubclass', 'iter', 'len', 'map', 'max', 'min', 'next', 'oct', 'open', 'ord', 'pow', 'print', 'range', 'repr', 'reversed', 'round', 'setattr', 'sorted', 'sum', 'super', 'vars', 'zip'],
                        operators: ['+', '-', '*', '/', '//', '%', '**', '=', '==', '!=', '<', '>', '<=', '>=', 'and', 'or', 'not', 'in', 'is', '&', '|', '^', '~', '<<', '>>', '+=', '-=', '*=', '/=', '//=', '%=', '**=', '&=', '|=', '^=', '<<=', '>>='],
                        brackets: ['(', ')', '[', ']', '{', '}'],
                        strings: ['\'', '"', '"""', '\'\'\''],
                        comments: ['#'],
                        numbers: /\b\d+(\.\d+)?([eE][+-]?\d+)?\b/g
                    },
                    json: {
                        keywords: ['true', 'false', 'null'],
                        types: [],
                        builtins: [],
                        operators: [':', ','],
                        brackets: ['{', '}', '[', ']'],
                        strings: ['"'],
                        comments: [],
                        numbers: /\b-?\d+(\.\d+)?([eE][+-]?\d+)?\b/g
                    },
                    markdown: {
                        keywords: [],
                        types: [],
                        builtins: [],
                        operators: ['#', '*', '_', '`', '[', ']', '(', ')', '!', '-', '+', '|'],
                        brackets: ['[', ']', '(', ')'],
                        strings: ['`'],
                        comments: [],
                        numbers: /\b\d+\b/g
                    },
                    text: {
                        keywords: [],
                        types: [],
                        builtins: [],
                        operators: [],
                        brackets: [],
                        strings: [],
                        comments: [],
                        numbers: /\b\d+\b/g
                    }
                };
                
                // 防抖函数
                const debounce = (func, wait) => {
                    let timeout;
                    return function executedFunction(...args) {
                        const later = () => {
                            clearTimeout(timeout);
                            func(...args);
                        };
                        clearTimeout(timeout);
                        timeout = setTimeout(later, wait);
                    };
                };
                
                // HTML转义
                const escapeHtml = (text) => {
                    const div = document.createElement('div');
                    div.textContent = text;
                    return div.innerHTML;
                };
                
                // 高亮关键字
                const highlightKeywords = (content, keywords) => {
                    if (!keywords || keywords.length === 0) return content;
                    keywords.forEach(keyword => {
                        const regex = new RegExp(`\\b${keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'g');
                        content = content.replace(regex, `<span class="keyword">${keyword}</span>`);
                    });
                    return content;
                };
                
                // 高亮类型
                const highlightTypes = (content, types) => {
                    if (!types || types.length === 0) return content;
                    types.forEach(type => {
                        const regex = new RegExp(`\\b${type.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'g');
                        content = content.replace(regex, `<span class="type">${type}</span>`);
                    });
                    return content;
                };
                
                // 高亮内置函数
                const highlightBuiltins = (content, builtins) => {
                    if (!builtins || builtins.length === 0) return content;
                    builtins.forEach(builtin => {
                        const regex = new RegExp(`\\b${builtin.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'g');
                        content = content.replace(regex, `<span class="builtin">${builtin}</span>`);
                    });
                    return content;
                };
                
                // 高亮字符串
                const highlightStrings = (content, stringChars) => {
                    if (!stringChars || stringChars.length === 0) return content;
                    stringChars.forEach(char => {
                        if (char === '"""' || char === '\'\'\'') {
                            // 处理三引号字符串
                            const regex = new RegExp(`${char}[\\s\\S]*?${char}`, 'g');
                            content = content.replace(regex, match => `<span class="string">${match}</span>`);
                        } else {
                            // 处理普通字符串
                            const escapedChar = char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                            const regex = new RegExp(`${escapedChar}([^${escapedChar}\\\\]|\\\\.)*${escapedChar}`, 'g');
                            content = content.replace(regex, match => `<span class="string">${match}</span>`);
                        }
                    });
                    return content;
                };
                
                // 高亮注释
                const highlightComments = (content, commentTypes) => {
                    if (!commentTypes || commentTypes.length === 0) return content;
                    
                    // 单行注释
                    if (commentTypes.includes('//')) {
                        content = content.replace(/\/\/.*$/gm, match => `<span class="comment">${match}</span>`);
                    }
                    
                    // Python注释
                    if (commentTypes.includes('#')) {
                        content = content.replace(/#.*$/gm, match => `<span class="comment">${match}</span>`);
                    }
                    
                    // 多行注释
                    if (commentTypes.includes('/*') && commentTypes.includes('*/')) {
                        content = content.replace(/\/\*[\s\S]*?\*\//g, match => `<span class="comment">${match}</span>`);
                    }
                    
                    // HTML注释
                    if (commentTypes.includes('<!--') && commentTypes.includes('-->')) {
                        content = content.replace(/<!--[\s\S]*?-->/g, match => `<span class="comment">${match}</span>`);
                    }
                    
                    return content;
                };
                
                // 高亮数字
                const highlightNumbers = (content, numberRegex) => {
                    if (!numberRegex) return content;
                    return content.replace(numberRegex, match => `<span class="number">${match}</span>`);
                };
                
                // 高亮操作符
                const highlightOperators = (content, operators) => {
                    if (!operators || operators.length === 0) return content;
                    // 按长度排序，先处理长的操作符
                    const sortedOperators = operators.sort((a, b) => b.length - a.length);
                    sortedOperators.forEach(op => {
                        const escapedOp = op.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                        const regex = new RegExp(escapedOp, 'g');
                        content = content.replace(regex, `<span class="operator">${op}</span>`);
                    });
                    return content;
                };
                
                // 高亮括号
                const highlightBrackets = (content, brackets) => {
                    if (!brackets || brackets.length === 0) return content;
                    brackets.forEach(bracket => {
                        const escapedBracket = bracket.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
                        const regex = new RegExp(escapedBracket, 'g');
                        content = content.replace(regex, `<span class="bracket">${bracket}</span>`);
                    });
                    return content;
                };
                
                // 语言检测
                const detectLanguage = (content) => {
                    if (!content.trim()) return 'text';
                    
                    // HTML检测
                    if (/<\/?[a-z][\s\S]*>/i.test(content)) {
                        return 'html';
                    }
                    
                    // CSS检测
                    if (/[a-z-]+\s*:\s*[^;]+;/i.test(content) || /{[^}]*}/i.test(content)) {
                        return 'css';
                    }
                    
                    // JSON检测
                    try {
                        JSON.parse(content);
                        return 'json';
                    } catch (e) {
                        // 不是有效的JSON
                    }
                    
                    // Python检测
                    if (/def\s+\w+\s*\(|import\s+\w+|from\s+\w+\s+import|#.*$/m.test(content)) {
                        return 'python';
                    }
                    
                    // JavaScript检测
                    if (/function\s+\w+\s*\(|var\s+\w+|let\s+\w+|const\s+\w+|=>/m.test(content)) {
                        return 'javascript';
                    }
                    
                    // Markdown检测
                    if (/^#{1,6}\s+|\*\*.*\*\*|\*.*\*|`.*`|\[.*\]\(.*\)/m.test(content)) {
                        return 'markdown';
                    }
                    
                    return 'text';
                };
                
                // 应用主题
                const applyTheme = (theme) => {
                    const container = document.querySelector('.editor-container');
                    if (container) {
                        // 移除所有主题类
                        container.classList.remove('vs-dark', 'vs-light', 'monokai');
                        // 添加新主题类
                        container.classList.add(theme);
                    }
                };
                
                // 更新高亮
                const updateHighlight = debounce(() => {
                    if (!highlightEnabled.value || isHighlighting.value) return;
                    
                    isHighlighting.value = true;
                    
                    try {
                        let highlightedText = escapeHtml(content.value);
                        const lang = languages[currentLanguage.value];
                        
                        if (lang && currentLanguage.value !== 'text') {
                            // 按顺序应用高亮
                            highlightedText = highlightComments(highlightedText, lang.comments);
                            highlightedText = highlightStrings(highlightedText, lang.strings);
                            highlightedText = highlightNumbers(highlightedText, lang.numbers);
                            highlightedText = highlightKeywords(highlightedText, lang.keywords);
                            highlightedText = highlightTypes(highlightedText, lang.types);
                            highlightedText = highlightBuiltins(highlightedText, lang.builtins);
                            highlightedText = highlightOperators(highlightedText, lang.operators);
                            highlightedText = highlightBrackets(highlightedText, lang.brackets);
                        }
                        
                        highlightedContent.value = highlightedText;
                    } catch (error) {
                        console.error('高亮处理错误:', error);
                        highlightedContent.value = escapeHtml(content.value);
                    } finally {
                        isHighlighting.value = false;
                    }
                }, 100);
                
                // 滚动同步
                const handleScroll = () => {
                    const textarea = document.querySelector('.editor-textarea');
                    const highlightLayer = document.querySelector('.highlight-layer');
                    const lineNumbers = document.querySelector('.line-numbers');
                    
                    if (textarea && highlightLayer) {
                        highlightLayer.scrollTop = textarea.scrollTop;
                        highlightLayer.scrollLeft = textarea.scrollLeft;
                    }
                    
                    if (textarea && lineNumbers) {
                        lineNumbers.scrollTop = textarea.scrollTop;
                    }
                };
                
                // 切换高亮
                const toggleHighlight = () => {
                    highlightEnabled.value = !highlightEnabled.value;
                    if (highlightEnabled.value) {
                        updateHighlight();
                        showToast('语法高亮已启用', 'success');
                    } else {
                        showToast('语法高亮已禁用', 'warning');
                    }
                    saveUserSettings();
                };
                
                // 切换行号
                const toggleLineNumbers = () => {
                    showLineNumbers.value = !showLineNumbers.value;
                    showToast(showLineNumbers.value ? '行号已显示' : '行号已隐藏', 'success');
                    saveUserSettings();
                };
                
                // 更新语言
                const updateLanguage = () => {
                    if (highlightEnabled.value) {
                        updateHighlight();
                    }
                    saveUserSettings();
                };
                
                // 更新主题
                const updateTheme = () => {
                    applyTheme(currentTheme.value);
                    saveUserSettings();
                };
                
                // 字数统计函数
                const calculateStats = (text) => {
                    if (!text) {
                        return {
                            characters: 0,
                            words: 0,
                            lines: 0,
                            nonEmptyLines: 0,
                            paragraphs: 0
                        };
                    }
                    
                    const lines = text.split('\n');
                    const nonEmptyLines = lines.filter(line => line.trim().length > 0);
                    const paragraphs = text.split(/\n\s*\n/).filter(p => p.trim().length > 0);
                    
                    return {
                        characters: text.length,
                        words: countWords(text),
                        lines: lines.length,
                        nonEmptyLines: nonEmptyLines.length,
                        paragraphs: paragraphs.length
                    };
                };
                
                const countWords = (text) => {
                    if (!text || !text.trim()) return 0;
                    return text.trim().split(/\s+/).length;
                };
                
                const formatNumber = (num) => {
                    return num.toLocaleString();
                };
                
                const toggleStatsPanel = () => {
                    showStatsPanel.value = !showStatsPanel.value;
                    if (showStatsPanel.value) {
                        showToast('字数统计面板已打开', 'success');
                    }
                };
                
                // 文件操作
                const newFile = () => {
                    if (content.value && !confirm('当前文档未保存，确定要新建文件吗？')) {
                        return;
                    }
                    content.value = '';
                    currentFileName.value = '';
                    saveStatus.value = '新文档';
                    initializeHistory();
                    showToast('新文件已创建', 'success');
                };
                
                const openFile = () => {
                    const input = document.createElement('input');
                    input.type = 'file';
                    input.accept = '.txt,.js,.html,.css,.py,.json,.md';
                    input.onchange = (e) => {
                        const file = e.target.files[0];
                        if (file) {
                            const reader = new FileReader();
                            reader.onload = (e) => {
                                content.value = e.target.result;
                                currentFileName.value = file.name;
                                saveStatus.value = '已打开';
                                initializeHistory();
                                
                                // 自动检测语言
                                const detectedLang = detectLanguage(content.value);
                                if (detectedLang !== currentLanguage.value) {
                                    currentLanguage.value = detectedLang;
                                    updateLanguage();
                                }
                                
                                showToast(`文件 "${file.name}" 已打开`, 'success');
                            };
                            reader.readAsText(file);
                        }
                    };
                    input.click();
                };
                
                const saveFile = () => {
                    if (!currentFileName.value) {
                        saveAsFile();
                        return;
                    }
                    
                    downloadFile(content.value, currentFileName.value);
                    saveStatus.value = '已保存';
                    showToast('文件已保存', 'success');
                };
                
                const saveAsFile = async () => {
                    try {
                        const fileName = await showPrompt('另存为', '请输入文件名:', currentFileName.value || 'untitled.txt');
                        if (fileName) {
                            downloadFile(content.value, fileName);
                            currentFileName.value = fileName;
                            saveStatus.value = '已保存';
                            showToast(`文件已另存为 "${fileName}"`, 'success');
                        }
                    } catch (error) {
                        // 用户取消
                    }
                };
                
                const downloadFile = (content, filename) => {
                    const blob = new Blob([content], { type: 'text/plain' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = filename;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                };
                
                // 历史记录管理
                const initializeHistory = () => {
                    history.value = [content.value];
                    historyIndex.value = 0;
                };
                
                const saveToHistory = (newContent) => {
                    if (history.value[historyIndex.value] === newContent) {
                        return;
                    }
                    
                    // 删除当前位置之后的历史记录
                    history.value = history.value.slice(0, historyIndex.value + 1);
                    
                    // 添加新的历史记录
                    history.value.push(newContent);
                    historyIndex.value = history.value.length - 1;
                    
                    // 限制历史记录大小
                    if (history.value.length > maxHistorySize) {
                        history.value = history.value.slice(-maxHistorySize);
                        historyIndex.value = history.value.length - 1;
                    }
                };
                
                const undo = () => {
                    if (canUndo.value) {
                        historyIndex.value--;
                        content.value = history.value[historyIndex.value];
                        showToast('已撤销', 'success');
                    }
                };
                
                const redo = () => {
                    if (canRedo.value) {
                        historyIndex.value++;
                        content.value = history.value[historyIndex.value];
                        showToast('已重做', 'success');
                    }
                };
                
                // 编辑操作
                const cut = async () => {
                    if (selectedText.value) {
                        try {
                            await navigator.clipboard.writeText(selectedText.value);
                            const textarea = document.querySelector('.editor-textarea');
                            const start = textarea.selectionStart;
                            const end = textarea.selectionEnd;
                            const newContent = content.value.substring(0, start) + content.value.substring(end);
                            content.value = newContent;
                            textarea.setSelectionRange(start, start);
                            showToast('已剪切到剪贴板', 'success');
                        } catch (err) {
                            showToast('剪切失败', 'error');
                        }
                    }
                };
                
                const copy = async () => {
                    if (selectedText.value) {
                        try {
                            await navigator.clipboard.writeText(selectedText.value);
                            showToast('已复制到剪贴板', 'success');
                        } catch (err) {
                            showToast('复制失败', 'error');
                        }
                    }
                };
                
                const paste = async () => {
                    try {
                        const text = await navigator.clipboard.readText();
                        const textarea = document.querySelector('.editor-textarea');
                        const start = textarea.selectionStart;
                        const end = textarea.selectionEnd;
                        const newContent = content.value.substring(0, start) + text + content.value.substring(end);
                        content.value = newContent;
                        
                        nextTick(() => {
                            textarea.setSelectionRange(start + text.length, start + text.length);
                        });
                        
                        showToast('已粘贴', 'success');
                    } catch (err) {
                        showToast('粘贴失败', 'error');
                    }
                };
                
                const selectAll = () => {
                    const textarea = document.querySelector('.editor-textarea');
                    if (textarea) {
                        textarea.select();
                        showToast('已全选', 'success');
                    }
                };
                
                // 格式设置
                const increaseFontSize = () => {
                    if (fontSize.value < 24) {
                        fontSize.value++;
                        saveUserSettings();
                        showToast(`字体大小: ${fontSize.value}px`, 'success');
                    }
                };
                
                const decreaseFontSize = () => {
                    if (fontSize.value > 10) {
                        fontSize.value--;
                        saveUserSettings();
                        showToast(`字体大小: ${fontSize.value}px`, 'success');
                    }
                };
                
                const changeFontFamily = () => {
                    const fonts = ['monospace', 'Arial', 'Times New Roman', 'Courier New', 'Georgia', 'Verdana'];
                    const currentIndex = fonts.indexOf(fontFamily.value);
                    const nextIndex = (currentIndex + 1) % fonts.length;
                    fontFamily.value = fonts[nextIndex];
                    saveUserSettings();
                    showToast(`字体: ${fontFamily.value}`, 'success');
                };
                
                const toggleWordWrap = () => {
                    wordWrap.value = !wordWrap.value;
                    saveUserSettings();
                    showToast(wordWrap.value ? '自动换行已开启' : '自动换行已关闭', 'success');
                };
                
                const toggleFullscreen = () => {
                    if (!document.fullscreenElement) {
                        document.documentElement.requestFullscreen();
                        isFullscreen.value = true;
                        showToast('已进入全屏模式', 'success');
                    } else {
                        document.exitFullscreen();
                        isFullscreen.value = false;
                        showToast('已退出全屏模式', 'success');
                    }
                };
                
                // 查找替换功能
                const toggleSearchPanel = () => {
                    showSearchPanel.value = !showSearchPanel.value;
                    if (showSearchPanel.value) {
                        nextTick(() => {
                            const searchInput = document.querySelector('.search-input');
                            if (searchInput) {
                                searchInput.focus();
                                if (selectedText.value) {
                                    searchText.value = selectedText.value;
                                }
                            }
                        });
                        showToast('查找面板已打开', 'success');
                    } else {
                        showToast('查找面板已关闭', 'success');
                    }
                };
                
                const toggleFindPanel = () => {
                    showFindPanel.value = !showFindPanel.value;
                    if (showFindPanel.value) {
                        nextTick(() => {
                            const findInput = document.querySelector('.find-input');
                            if (findInput) {
                                findInput.focus();
                                if (selectedText.value) {
                                    searchText.value = selectedText.value;
                                }
                            }
                        });
                    }
                };
                
                const performSearch = () => {
                    if (!searchText.value) {
                        searchMatches.value = [];
                        currentMatchIndex.value = -1;
                        return;
                    }
                    
                    const text = content.value;
                    const searchPattern = caseSensitive.value ? searchText.value : searchText.value.toLowerCase();
                    const targetText = caseSensitive.value ? text : text.toLowerCase();
                    
                    const matches = [];
                    let index = 0;
                    
                    while (index < targetText.length) {
                        const foundIndex = targetText.indexOf(searchPattern, index);
                        if (foundIndex === -1) break;
                        
                        matches.push({
                            start: foundIndex,
                            end: foundIndex + searchText.value.length
                        });
                        
                        index = foundIndex + 1;
                    }
                    
                    searchMatches.value = matches;
                    currentMatchIndex.value = matches.length > 0 ? 0 : -1;
                    
                    if (matches.length > 0) {
                        highlightMatches();
                        jumpToMatch(0);
                    }
                };
                
                const findNext = () => {
                    if (searchMatches.value.length === 0) {
                        performSearch();
                        return;
                    }
                    
                    currentMatchIndex.value = (currentMatchIndex.value + 1) % searchMatches.value.length;
                    jumpToMatch(currentMatchIndex.value);
                };
                
                const findPrevious = () => {
                    if (searchMatches.value.length === 0) {
                        performSearch();
                        return;
                    }
                    
                    currentMatchIndex.value = currentMatchIndex.value <= 0 
                        ? searchMatches.value.length - 1 
                        : currentMatchIndex.value - 1;
                    jumpToMatch(currentMatchIndex.value);
                };
                
                const jumpToMatch = (index) => {
                    if (index < 0 || index >= searchMatches.value.length) return;
                    
                    const match = searchMatches.value[index];
                    const textarea = document.querySelector('.editor-textarea');
                    if (textarea) {
                        textarea.focus();
                        textarea.setSelectionRange(match.start, match.end);
                        
                        // 滚动到可见区域
                        const lines = content.value.substring(0, match.start).split('\n');
                        const lineNumber = lines.length;
                        const lineHeight = 20; // 假设行高
                        const scrollTop = (lineNumber - 1) * lineHeight - textarea.clientHeight / 2;
                        textarea.scrollTop = Math.max(0, scrollTop);
                    }
                };
                
                const highlightMatches = () => {
                    // 这里可以添加高亮显示逻辑
                    // 由于我们使用的是textarea，高亮显示比较复杂
                    // 可以考虑使用overlay或者其他方式实现
                };
                
                const replaceOne = () => {
                    if (currentMatchIndex.value === -1 || searchMatches.value.length === 0) {
                        return;
                    }
                    
                    const match = searchMatches.value[currentMatchIndex.value];
                    const newContent = content.value.substring(0, match.start) + 
                                     replaceText.value + 
                                     content.value.substring(match.end);
                    
                    content.value = newContent;
                    
                    // 重新搜索
                    performSearch();
                    
                    showToast('已替换', 'success');
                };
                
                const replace = () => {
                    if (currentMatchIndex.value === -1 || searchMatches.value.length === 0) {
                        return;
                    }
                    
                    const match = searchMatches.value[currentMatchIndex.value];
                    const newContent = content.value.substring(0, match.start) + 
                                     replaceText.value + 
                                     content.value.substring(match.end);
                    
                    content.value = newContent;
                    
                    // 重新搜索
                    performSearch();
                    
                    showToast('已替换', 'success');
                };
                
                const replaceAll = () => {
                    if (!searchText.value) {
                        showToast('请输入查找内容', 'warning');
                        return;
                    }
                    
                    const searchPattern = caseSensitive.value ? searchText.value : searchText.value.toLowerCase();
                    const targetText = caseSensitive.value ? content.value : content.value.toLowerCase();
                    
                    let count = 0;
                    let newContent = content.value;
                    let lastIndex = 0;
                    let result = '';
                    
                    while (lastIndex < targetText.length) {
                        const foundIndex = targetText.indexOf(searchPattern, lastIndex);
                        if (foundIndex === -1) {
                            result += newContent.substring(lastIndex);
                            break;
                        }
                        
                        result += newContent.substring(lastIndex, foundIndex) + replaceText.value;
                        lastIndex = foundIndex + searchText.value.length;
                        count++;
                    }
                    
                    if (count > 0) {
                        content.value = result;
                        performSearch();
                        showToast(`已替换 ${count} 处`, 'success');
                    } else {
                        showToast('未找到匹配项', 'warning');
                    }
                };
                
                // 输入处理
                const handleInput = (event) => {
                    const newContent = event.target.value;
                    content.value = newContent;
                    saveStatus.value = '未保存';
                    
                    // 防抖保存到历史记录
                    debouncedSaveToHistory(newContent);
                    
                    // 更新高亮
                    if (highlightEnabled.value) {
                        debouncedUpdateHighlight();
                    }
                    
                    // 自动检测语言
                    const detectedLang = detectLanguage(newContent);
                    if (detectedLang !== currentLanguage.value) {
                        currentLanguage.value = detectedLang;
                        updateLanguage();
                    }
                };
                
                // 键盘事件处理
                const handleKeydown = (event) => {
                    // Ctrl+S 保存
                    if (event.ctrlKey && event.key === 's') {
                        event.preventDefault();
                        saveFile();
                        return;
                    }
                    
                    // Ctrl+N 新建
                    if (event.ctrlKey && event.key === 'n') {
                        event.preventDefault();
                        newFile();
                        return;
                    }
                    
                    // Ctrl+O 打开
                    if (event.ctrlKey && event.key === 'o') {
                        event.preventDefault();
                        openFile();
                        return;
                    }
                    
                    // Ctrl+F 查找
                    if (event.ctrlKey && event.key === 'f') {
                        event.preventDefault();
                        toggleFindPanel();
                        return;
                    }
                    
                    // Ctrl+A 全选
                    if (event.ctrlKey && event.key === 'a') {
                        event.preventDefault();
                        selectAll();
                        return;
                    }
                    
                    // Ctrl+Z 撤销
                    if (event.ctrlKey && event.key === 'z' && !event.shiftKey) {
                        event.preventDefault();
                        undo();
                        return;
                    }
                    
                    // Ctrl+Y 或 Ctrl+Shift+Z 重做
                    if ((event.ctrlKey && event.key === 'y') || 
                        (event.ctrlKey && event.shiftKey && event.key === 'z')) {
                        event.preventDefault();
                        redo();
                        return;
                    }
                    
                    // Ctrl+X 剪切
                    if (event.ctrlKey && event.key === 'x') {
                        event.preventDefault();
                        cut();
                        return;
                    }
                    
                    // Ctrl+C 复制
                    if (event.ctrlKey && event.key === 'c') {
                        event.preventDefault();
                        copy();
                        return;
                    }
                    
                    // Ctrl+V 粘贴
                    if (event.ctrlKey && event.key === 'v') {
                        event.preventDefault();
                        paste();
                        return;
                    }
                    
                    // Ctrl+= 增大字体
                    if (event.ctrlKey && event.key === '=') {
                        event.preventDefault();
                        increaseFontSize();
                        return;
                    }
                    
                    // Ctrl+- 减小字体
                    if (event.ctrlKey && event.key === '-') {
                        event.preventDefault();
                        decreaseFontSize();
                        return;
                    }
                    
                    // Ctrl+Shift+S 字数统计
                    if (event.ctrlKey && event.shiftKey && event.key === 'S') {
                        event.preventDefault();
                        toggleStatsPanel();
                        return;
                    }
                    
                    // F11 全屏
                    if (event.key === 'F11') {
                        event.preventDefault();
                        toggleFullscreen();
                        return;
                    }
                };
                
                // 搜索面板快捷键
                const handleSearchKeydown = (event) => {
                    if (event.key === 'Enter') {
                        event.preventDefault();
                        if (event.shiftKey) {
                            findPrevious();
                        } else {
                            findNext();
                        }
                    } else if (event.key === 'Escape') {
                        showSearchPanel.value = false;
                    }
                };
                
                // 查找面板快捷键
                const handleFindKeydown = (event) => {
                    if (event.key === 'Enter') {
                        event.preventDefault();
                        if (event.shiftKey) {
                            findPrevious();
                        } else {
                            findNext();
                        }
                    } else if (event.key === 'Escape') {
                        showFindPanel.value = false;
                    }
                };
                
                // 全屏事件处理
                const handleFullscreenChange = () => {
                    isFullscreen.value = !!document.fullscreenElement;
                };
                
                // 选择变化处理
                const handleSelectionChange = () => {
                    const textarea = document.querySelector('.editor-textarea');
                    if (textarea && document.activeElement === textarea) {
                        const start = textarea.selectionStart;
                        const end = textarea.selectionEnd;
                        
                        selectionStart.value = start;
                        selectionEnd.value = end;
                        selectedText.value = content.value.substring(start, end);
                        
                        // 更新光标位置信息
                        updateCursorPosition(start);
                    }
                };
                
                // 更新光标位置
                const updateCursorPosition = (position) => {
                    const textBeforeCursor = content.value.substring(0, position);
                    const lines = textBeforeCursor.split('\n');
                    cursorLine.value = lines.length;
                    cursorColumn.value = lines[lines.length - 1].length + 1;
                };
                
                // 右键菜单
                const showContextMenu = (event) => {
                    event.preventDefault();
                    contextMenuVisible.value = true;
                    contextMenuX.value = event.clientX;
                    contextMenuY.value = event.clientY;
                };
                
                const hideContextMenu = () => {
                    contextMenuVisible.value = false;
                };
                
                // 文件拖拽处理
                const handleDragOver = (event) => {
                    event.preventDefault();
                    event.dataTransfer.dropEffect = 'copy';
                };
                
                const handleDrop = (event) => {
                    event.preventDefault();
                    const files = event.dataTransfer.files;
                    if (files.length > 0) {
                        const file = files[0];
                        if (file.type.startsWith('text/') || 
                            file.name.match(/\.(txt|js|html|css|py|json|md)$/i)) {
                            const reader = new FileReader();
                            reader.onload = (e) => {
                                content.value = e.target.result;
                                currentFileName.value = file.name;
                                saveStatus.value = '已打开';
                                initializeHistory();
                                
                                // 自动检测语言
                                const detectedLang = detectLanguage(content.value);
                                if (detectedLang !== currentLanguage.value) {
                                    currentLanguage.value = detectedLang;
                                    updateLanguage();
                                }
                                
                                showToast(`文件 "${file.name}" 已打开`, 'success');
                            };
                            reader.readAsText(file);
                        } else {
                            showToast('不支持的文件类型', 'error');
                        }
                    }
                };
                
                // 监听内容变化
                watch(content, (newContent) => {
                    if (highlightEnabled.value) {
                        debouncedUpdateHighlight();
                    }
                });
                
                // 监听搜索文本变化
                watch(searchText, () => {
                    if (searchText.value) {
                        performSearch();
                    } else {
                        searchMatches.value = [];
                        currentMatchIndex.value = -1;
                    }
                });
                
                // 时间更新
                const updateTime = () => {
                    currentTime.value = new Date().toLocaleString();
                };
                
                // Toast 提示
                const showToast = (message, type = 'info') => {
                    toastMessage.value = message;
                    toastType.value = type;
                    toastVisible.value = true;
                    
                    setTimeout(() => {
                        toastVisible.value = false;
                    }, 3000);
                };
                
                // 模态框
                const showAlert = (message) => {
                    return new Promise((resolve) => {
                        modalType.value = 'alert';
                        modalTitle.value = '提示';
                        modalMessage.value = message;
                        modalVisible.value = true;
                        modalResolve.value = resolve;
                    });
                };
                
                const showConfirm = (message) => {
                    return new Promise((resolve) => {
                        modalType.value = 'confirm';
                        modalTitle.value = '确认';
                        modalMessage.value = message;
                        modalVisible.value = true;
                        modalResolve.value = resolve;
                    });
                };
                
                const showPrompt = (title, message, defaultValue = '') => {
                    return new Promise((resolve, reject) => {
                        modalType.value = 'prompt';
                        modalTitle.value = title;
                        modalMessage.value = message;
                        modalInputValue.value = defaultValue;
                        modalVisible.value = true;
                        modalResolve.value = resolve;
                        modalReject.value = reject;
                    });
                };
                
                const handleModalConfirm = () => {
                    modalVisible.value = false;
                    if (modalType.value === 'prompt') {
                        modalResolve.value(modalInputValue.value);
                    } else {
                        modalResolve.value(true);
                    }
                };
                
                const handleModalCancel = () => {
                    modalVisible.value = false;
                    if (modalType.value === 'prompt') {
                        modalReject.value(new Error('User cancelled'));
                    } else {
                        modalResolve.value(false);
                    }
                };
                
                // 用户设置
                const saveUserSettings = () => {
                    const settings = {
                        fontSize: fontSize.value,
                        fontFamily: fontFamily.value,
                        wordWrap: wordWrap.value,
                        highlightEnabled: highlightEnabled.value,
                        showLineNumbers: showLineNumbers.value,
                        currentLanguage: currentLanguage.value,
                        currentTheme: currentTheme.value
                    };
                    localStorage.setItem('textEditorSettings', JSON.stringify(settings));
                };
                
                const loadUserSettings = () => {
                    try {
                        const settings = JSON.parse(localStorage.getItem('textEditorSettings') || '{}');
                        if (settings.fontSize) fontSize.value = settings.fontSize;
                        if (settings.fontFamily) fontFamily.value = settings.fontFamily;
                        if (settings.wordWrap !== undefined) wordWrap.value = settings.wordWrap;
                        if (settings.highlightEnabled !== undefined) highlightEnabled.value = settings.highlightEnabled;
                        if (settings.showLineNumbers !== undefined) showLineNumbers.value = settings.showLineNumbers;
                        if (settings.currentLanguage) currentLanguage.value = settings.currentLanguage;
                        if (settings.currentTheme) currentTheme.value = settings.currentTheme;
                    } catch (error) {
                        console.warn('Failed to load user settings:', error);
                    }
                };
                
                // 生命周期钩子
                onMounted(() => {
                    // 加载用户设置
                    loadUserSettings();
                    
                    // 应用主题
                    applyTheme(currentTheme.value);
                    
                    // 初始化历史记录
                    initializeHistory();
                    
                    // 更新时间
                    updateTime();
                    const timeInterval = setInterval(updateTime, 1000);
                    
                    // 添加全局事件监听
                    document.addEventListener('keydown', handleKeydown);
                    document.addEventListener('selectionchange', handleSelectionChange);
                    document.addEventListener('fullscreenchange', handleFullscreenChange);
                    document.addEventListener('click', hideContextMenu);
                    
                    // 添加拖拽事件监听
                    const editorContainer = document.querySelector('.editor-container');
                    if (editorContainer) {
                        editorContainer.addEventListener('dragover', handleDragOver);
                        editorContainer.addEventListener('drop', handleDrop);
                    }
                    
                    // 清理函数
                    onUnmounted(() => {
                        clearInterval(timeInterval);
                        document.removeEventListener('keydown', handleKeydown);
                        document.removeEventListener('selectionchange', handleSelectionChange);
                        document.removeEventListener('fullscreenchange', handleFullscreenChange);
                        document.removeEventListener('click', hideContextMenu);
                        
                        if (editorContainer) {
                            editorContainer.removeEventListener('dragover', handleDragOver);
                            editorContainer.removeEventListener('drop', handleDrop);
                        }
                    });
                });
                
                // 返回所有响应式数据和方法
                return {
                    // 基础数据
                    content,
                    currentFileName,
                    saveStatus,
                    currentTime,
                    
                    // 历史记录
                    history,
                    historyIndex,
                    maxHistorySize,
                    canUndo,
                    canRedo,
                    
                    // 选择和光标
                    selectedText,
                    selectionStart,
                    selectionEnd,
                    cursorLine,
                    cursorColumn,
                    cursorPosition,
                    
                    // 格式设置
                    fontSize,
                    fontFamily,
                    wordWrap,
                    isFullscreen,
                    
                    // 查找替换
                    showSearchPanel,
                    showFindPanel,
                    searchText,
                    replaceText,
                    caseSensitive,
                    wholeWord,
                    searchMatches,
                    currentMatchIndex,
                    
                    // 字数统计
                    showStatsPanel,
                    documentStats,
                    selectionStats,
                    
                    // 关键字高亮
                    highlightEnabled,
                    showLineNumbers,
                    currentLanguage,
                    currentTheme,
                    
                    // 右键菜单
                    contextMenuVisible,
                    contextMenuPosition,
                    contextMenuX,
                    contextMenuY,
                    
                    // Toast
                    toast,
                    toastVisible,
                    toastMessage,
                    toastType,
                    
                    // 模态框
                    modal,
                    modalVisible,
                    modalType,
                    modalTitle,
                    modalMessage,
                    modalInputValue,
                    modalResolve,
                    modalReject,
                    
                    // 计算属性
                    selectedTextLength,
                    contentLines,
                    totalMatches,
                    
                    // 方法
                    newFile,
                    openFile,
                    saveFile,
                    saveAsFile,
                    downloadFile,
                    undo,
                    redo,
                    cut,
                    copy,
                    paste,
                    selectAll,
                    increaseFontSize,
                    decreaseFontSize,
                    changeFontFamily,
                    toggleWordWrap,
                    toggleFullscreen,
                    toggleSearchPanel,
                    toggleFindPanel,
                    performSearch,
                    findNext,
                    findPrevious,
                    replaceOne,
                    replaceAll,
                    toggleStatsPanel,
                    toggleHighlight,
                    toggleLineNumbers,
                    updateLanguage,
                    updateTheme,
                    handleInput,
                    handleKeydown,
                    handleSearchKeydown,
                    handleFindKeydown,
                    showContextMenu,
                    hideContextMenu,
                    handleModalConfirm,
                    handleModalCancel,
                    showToast,
                    showAlert,
                    showConfirm,
                    showPrompt,
                    calculateStats,
                    countWords,
                    formatNumber
                };
            }
        }).mount('#app');
    </script>
</body>
</html>